package org.jadapter.tests;

import org.jadapter.Query;
import org.jadapter.graph.TransitiveClosure;
import org.jadapter.tests.examples.simple.impl.A;
import org.jadapter.tests.examples.simple.impl.B;
import org.jadapter.tests.examples.simple.impl.C;
import org.jadapter.tests.examples.simple.impl.D;
import org.jadapter.tests.examples.simple.impl.X;
import org.jadapter.tests.examples.simple.impl.Y;
import org.jadapter.tests.examples.simple.impl.Z;


public class TestTransitivity extends BaseTestCase {
    
    TransitiveClosure<Class<?>,Class<?>> graph;
    
    @Override
    public void setUp() {
        graph = new TransitiveClosure<Class<?>,Class<?>>(); 
    }
    
    public void testTo() {
        graph.insert(A.class,B.class,new Query<Class<?>>(X.class));
        Class<?> a = graph.to(B.class).iterator().next();
        assertEquals(A.class, a);
    }
    
    public void testFrom(){
        graph.insert(A.class,B.class,new Query<Class<?>>(X.class));
        Class<?> b = graph.from(A.class).iterator().next();
        assertEquals(B.class, b);        
    }

    
    public void testShouldNotContainDuplicates() {
        
        graph.insert(A.class,B.class, new Query<Class<?>>(X.class));
        assertEquals(1, graph.size());
        
        graph.insert(A.class,B.class, new Query<Class<?>>(X.class));
        assertEquals(1, graph.size());    
        
        graph.insert(C.class,D.class, new Query<Class<?>>(X.class));
        assertEquals(2, graph.size());    
    }
      
    
    public void testShouldReturnInsertedEdge(){
        graph.insert(B.class,A.class, new Query<Class<?>>(X.class));
        Query<Class<?>> edge = graph.get(B.class, A.class);
        assertNotNull(edge);
    }
    

    public void testShoulInferForwardRelationship(){
        graph.insert(A.class,B.class, new Query<Class<?>>(X.class));
        graph.insert(B.class,C.class, new Query<Class<?>>(Y.class));
        
        assertEquals(3, graph.size());  
        Query<Class<?>> query = graph.get(A.class, C.class);
        assertNotNull(query);
        
        assertQueryEquals(query, X.class, Y.class);
               
        graph.insert(C.class, D.class, new Query<Class<?>>(Z.class));
      
        assertQueryEquals(graph.get(A.class, D.class), X.class, Y.class, Z.class);     
        
    }
    
    
    public void testShouldInferBackwardRelationship(){
        graph.insert(B.class,C.class, new Query<Class<?>>(Y.class));
        graph.insert(A.class,B.class, new Query<Class<?>>(X.class));

        assertEquals(3, graph.size());  
        Query<Class<?>> query = graph.get(A.class, C.class);
        assertNotNull(query);
        
        assertQueryEquals(query, X.class, Y.class);
        
        
        graph.insert(C.class, D.class, new Query<Class<?>>(Z.class));
 
        
        assertQueryEquals(graph.get(A.class, D.class), X.class, Y.class, Z.class);          
        assertQueryEquals(graph.get(A.class, C.class), X.class, Y.class);          
        
    } 
}
